/**
 * 
 */
package com.hezuti.common.dao;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.omg.CORBA.portable.ApplicationException;

import com.hezuti.common.page.PageInfo;
import com.hezuti.common.utils.GenericsUtils;


/**
 * @author zczhang 扩展的有关实体的DAO类，使用泛型生成具有增删改功能的DAO类
 */
public class BaseHibernateDaoGeneric<T> extends BaseHibernateDao {

	/**
	 * 实体类 类声明
	 */
	protected Class<T> entityClass;

	/**
	 * 初始化，获得本类的子类声明中 父类的泛型类型
	 * 
	 * <pre>
	 *  如，本类的子类声明为
	 *    public userDAO extends HibernateEntityDaoGeneric<Users>
	 *    在本方法中entityClass将获得类Users.class
	 * </pre>
	 */
	@SuppressWarnings("unchecked")
	public BaseHibernateDaoGeneric() {
		entityClass = GenericsUtils.getSuperClassGenricType(getClass());
	}

	/**
	 * 获得实体类 类类型
	 * 
	 * @return
	 */
	private Class<T> getEntityClass() {
		return entityClass;
	}

	/**
	 * 查找一个对象,没有找到则抛出异常
	 * 
	 * @param id
	 * @return
	 * @throws ApplicationException
	 */
	public final T load(Serializable id) {
		return super.load(getEntityClass(), id);
	}

	/**
	 * 得到一个对象,没有返回null
	 * 
	 * @param id
	 * @return
	 */
	public final T get(Serializable id) {
		return super.get(getEntityClass(), id);
	}

	/**
	 * 根据传入的对象id列表,返回对应的对象列表
	 * 
	 * @param ids
	 * @return
	 */
	public final List<T> findListByIds(final List<Serializable> ids) {
		return super.findListByIds(getEntityClass(), ids);
	}

	/**
	 * 根据id删除一个对象
	 * 
	 * @param id
	 */
	public final void deleteById(Serializable id) {
		super.delete(getEntityClass(), id);
	}

	/**
	 * 根据指定的对象id列表,删除对应的对象
	 * 
	 * @param ids
	 */
	public final void deleteAll(List<Serializable> ids) {
		super.deleteAll(getEntityClass(), ids);
	}

	/**
	 * 清除某个对象cache
	 * 
	 * @param id
	 */
	public final void evict(final Serializable id) {
		super.evict(getEntityClass(), id);
	}

	/**
	 * 清楚list的cache
	 * 
	 * @param <T>
	 * @param idList
	 */
	public final void evicts(final List<Serializable> idList) {
		super.evicts(getEntityClass(), idList);
	}

	/**
	 * 分页查询
	 */
	public List<T> pagedQuery(final PageInfo page, final Queryable q) {
		return super.pagedQuery(page, getEntityClass(), q);
	}

	/**
	 * 创建Criteria对象.
	 * 
	 * @param criterions
	 *            可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
	 */
	public Criteria createCriteria(Criterion... criterions) {
		return super.createCriteria(getEntityClass(), criterions);
	}

	/**
	 * 创建Criteria对象，带排序字段与升降序字段.
	 * 
	 * @see #createCriteria(Class,Criterion[])
	 */
	public Criteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions) {
		return super.createCriteria(getEntityClass(), orderBy, isAsc, criterions);
	}

	/**
	 * 根据属性名和属性值查询对象.
	 * 
	 * @return 符合条件的对象列表
	 */
	public List<T> findBy(String propertyName, Object value) {
		return super.findBy(getEntityClass(), propertyName, value);
	}

	/**
	 * 根据属性名和属性值模糊查找对象
	 * 
	 * @param entityClass
	 * @param propertyName
	 * @param value
	 *            字符型，如："%广告%"
	 * @return
	 */
	public List<T> findByLike(String propertyName, String value) {
		return super.findByLike(getEntityClass(), propertyName, value);
	}

	/**
	 * 根据属性名和属性值查询对象,带排序参数.
	 */
	public List<T> findBy(String propertyName, Object value, String orderBy, boolean isAsc) {
		return super.findBy(getEntityClass(), propertyName, value);
	}

	/**
	 * 根据事例查找持久对象
	 * 
	 * @param entityClass
	 * @param instance
	 * @return
	 */
	public List<T> findByExample(final Object instance, final String orderBy, final Boolean isAsc, final Boolean islike, final Criterion... criterions) {
		return super.findByExample(getEntityClass(), instance, orderBy, isAsc, islike, criterions);
	}

	/**
	 * 根据事例查找持久对象
	 * 
	 * @param entityClass
	 * @param instance
	 * @return
	 */
	public List<T> findByExample(Object instance, Boolean islike, Criterion... criterions) {
		return super.findByExample(getEntityClass(), instance, islike, criterions);
	}

	/**
	 * 根据事例查找持久对象
	 * 
	 * @param entityClass
	 * @param instance
	 * @return
	 */
	public List<T> findByExample(Object instance, Boolean islike) {
		return super.findByExample(getEntityClass(), instance, islike);
	}

	/**
	 * 根据属性名和属性值查询唯一对象.
	 * 
	 * @return 符合条件的唯一对象 or null if not found.
	 */
	public T findUniqueBy(String propertyName, Object value) {
		return super.findUniqueBy(getEntityClass(), propertyName, value);
	}

	/**
	 * 根据Criteria查询唯一对象.
	 * 
	 * @return 符合条件的唯一对象 or null if not found.
	 */
	public T findUniqueBy(Criteria criteria) {
		return super.findUniqueBy(entityClass, criteria);
	}

	/**
	 * 根据Criteria查询出记录列表
	 * 
	 * @param criteria
	 * @return
	 */
	public List<T> findBy(Criteria criteria) {
		return super.findBy(entityClass, criteria);
	}

	/**
	 * 获得全部数据
	 */
	public List<T> getAll() {
		return super.getAll(getEntityClass());
	}

	/**
	 * 获取全部对象,带排序字段与升降序参数.
	 */
	public List<T> getAll(String orderBy, boolean isAsc) {
		return super.getAll(getEntityClass(), orderBy, isAsc);
	}

	/**
	 * 取得对象的主键值,辅助函数.
	 */
	public Serializable getId(Object entity) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
		return super.getId(getEntityClass(), entity);
	}

	/**
	 * 取得对象的主键名,辅助函数.
	 */
	@SuppressWarnings("unchecked")
	public String getIdName(Class clazz) {
		return super.getIdName(getEntityClass());
	}

	/**
	 * 判断对象某些属性的值在数据库中是否唯一.
	 * 
	 * @param uniquePropertyNames
	 *            在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
	 */
	public boolean isUnique(Object entity, String uniquePropertyNames) {
		return super.isUnique(getEntityClass(), entity, uniquePropertyNames);
	}

	/**
	 * 合并对象，与数据库中已存在对象合并数据字段，重新关联托管对象 随时合并你的的改动而不考虑session的状态
	 * 
	 * @param detachedInstance
	 * @param skipField
	 *            跳过的字段，不合并的字段，多字段逗号分开
	 * @return
	 */
	public T merge(T detachedInstance, String skipField) {
		return super.merge(getEntityClass(), detachedInstance, skipField);
	}

	/**
	 * 合并对象，与数据库中已存在对象合并数据字段，重新关联托管对象 随时合并你的的改动而不考虑session的状态
	 * 
	 * @param detachedInstance
	 * @param skipField
	 *            跳过的字段，不合并的字段，多字段逗号分开
	 * @return
	 */
	public T merge(T detachedInstance) {
		return super.merge(getEntityClass(), detachedInstance);
	}

}
